package common

import (
	"fmt"
	"log"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// BalanceValidator 余额验证器
type BalanceValidator struct {
	db *gorm.DB
}

// NewBalanceValidator 创建余额验证器
func NewBalanceValidator() *BalanceValidator {
	return &BalanceValidator{
		db: database.DB,
	}
}

// ValidateAllBalances 验证所有余额的完整性
func (v *BalanceValidator) ValidateAllBalances() error {
	log.Println("开始验证所有余额的完整性...")

	// 1. 验证主账号余额
	if err := v.validateMasterAccountBalances(); err != nil {
		return fmt.Errorf("主账号余额验证失败: %v", err)
	}

	// 2. 验证子账号余额
	if err := v.validateSubAccountBalances(); err != nil {
		return fmt.Errorf("子账号余额验证失败: %v", err)
	}

	// 3. 验证资金记录一致性
	if err := v.validateFundRecords(); err != nil {
		return fmt.Errorf("资金记录验证失败: %v", err)
	}

	log.Println("所有余额验证完成")
	return nil
}

// validateMasterAccountBalances 验证主账号余额
func (v *BalanceValidator) validateMasterAccountBalances() error {
	var masterAccounts []models.MasterAccount
	if err := v.db.Find(&masterAccounts).Error; err != nil {
		return fmt.Errorf("查询主账号失败: %v", err)
	}

	for _, master := range masterAccounts {
		// 检查余额是否为负数
		if master.Balance.LessThan(decimal.Zero) {
			log.Printf("警告：主账号 %d 余额为负数: %s", master.ID, master.Balance.String())
		}

		// 检查余额是否异常巨大
		if master.Balance.GreaterThan(decimal.NewFromFloat(1000000)) {
			log.Printf("警告：主账号 %d 余额异常巨大: %s", master.ID, master.Balance.String())
		}

		// 检查余额精度（应该是2位小数）
		if !master.Balance.Equal(master.Balance.Round(2)) {
			log.Printf("警告：主账号 %d 余额精度异常: %s", master.ID, master.Balance.String())
		}
	}

	return nil
}

// validateSubAccountBalances 验证子账号余额
func (v *BalanceValidator) validateSubAccountBalances() error {
	var subAccounts []models.SubAccount
	if err := v.db.Find(&subAccounts).Error; err != nil {
		return fmt.Errorf("查询子账号失败: %v", err)
	}

	for _, sub := range subAccounts {
		// 检查余额是否为负数
		if sub.Balance.LessThan(decimal.Zero) {
			log.Printf("警告：子账号 %d 余额为负数: %s", sub.ID, sub.Balance.String())
		}

		// 检查余额是否异常巨大
		if sub.Balance.GreaterThan(decimal.NewFromFloat(1000000)) {
			log.Printf("警告：子账号 %d 余额异常巨大: %s", sub.ID, sub.Balance.String())
		}

		// 检查余额精度（应该是2位小数）
		if !sub.Balance.Equal(sub.Balance.Round(2)) {
			log.Printf("警告：子账号 %d 余额精度异常: %s", sub.ID, sub.Balance.String())
		}
	}

	return nil
}

// validateFundRecords 验证资金记录一致性
func (v *BalanceValidator) validateFundRecords() error {
	// 验证主账号资金记录
	var funds []models.MasterSubAccountFund
	if err := v.db.Find(&funds).Error; err != nil {
		return fmt.Errorf("查询资金记录失败: %v", err)
	}

	for _, fund := range funds {
		// 检查金额是否为负数
		if fund.Amount.LessThan(decimal.Zero) {
			log.Printf("警告：资金记录 %d 金额为负数: %s", fund.ID, fund.Amount.String())
		}

		// 检查金额精度（应该是2位小数）
		if !fund.Amount.Equal(fund.Amount.Round(2)) {
			log.Printf("警告：资金记录 %d 金额精度异常: %s", fund.ID, fund.Amount.String())
		}
	}

	// 验证消费记录
	var consumeRecords []models.SubAccountConsumeRecord
	if err := v.db.Find(&consumeRecords).Error; err != nil {
		return fmt.Errorf("查询消费记录失败: %v", err)
	}

	for _, record := range consumeRecords {
		// 检查金额是否为负数
		if record.Amount.LessThan(decimal.Zero) {
			log.Printf("警告：消费记录 %d 金额为负数: %s", record.ID, record.Amount.String())
		}

		// 检查金额精度（应该是2位小数）
		if !record.Amount.Equal(record.Amount.Round(2)) {
			log.Printf("警告：消费记录 %d 金额精度异常: %s", record.ID, record.Amount.String())
		}
	}

	return nil
}

// GenerateBalanceReport 生成余额报告
func (v *BalanceValidator) GenerateBalanceReport() error {
	log.Println("生成余额报告...")

	// 主账号余额统计
	var masterStats struct {
		TotalAccounts int64           `json:"total_accounts"`
		TotalBalance  decimal.Decimal `json:"total_balance"`
		AvgBalance    decimal.Decimal `json:"avg_balance"`
		MaxBalance    decimal.Decimal `json:"max_balance"`
		MinBalance    decimal.Decimal `json:"min_balance"`
	}

	if err := v.db.Model(&models.MasterAccount{}).
		Select("COUNT(*) as total_accounts, SUM(balance) as total_balance, AVG(balance) as avg_balance, MAX(balance) as max_balance, MIN(balance) as min_balance").
		Scan(&masterStats).Error; err != nil {
		return fmt.Errorf("统计主账号余额失败: %v", err)
	}

	log.Printf("主账号余额统计: %+v", masterStats)

	// 子账号余额统计
	var subStats struct {
		TotalAccounts int64           `json:"total_accounts"`
		TotalBalance  decimal.Decimal `json:"total_balance"`
		AvgBalance    decimal.Decimal `json:"avg_balance"`
		MaxBalance    decimal.Decimal `json:"max_balance"`
		MinBalance    decimal.Decimal `json:"min_balance"`
	}

	if err := v.db.Model(&models.SubAccount{}).
		Select("COUNT(*) as total_accounts, SUM(balance) as total_balance, AVG(balance) as avg_balance, MAX(balance) as max_balance, MIN(balance) as min_balance").
		Scan(&subStats).Error; err != nil {
		return fmt.Errorf("统计子账号余额失败: %v", err)
	}

	log.Printf("子账号余额统计: %+v", subStats)

	return nil
}

// FixBalanceIssues 修复余额问题
func (v *BalanceValidator) FixBalanceIssues() error {
	log.Println("开始修复余额问题...")

	// 修复负数余额
	if err := v.db.Model(&models.MasterAccount{}).
		Where("balance < 0").
		Update("balance", decimal.Zero).Error; err != nil {
		return fmt.Errorf("修复主账号负数余额失败: %v", err)
	}

	if err := v.db.Model(&models.SubAccount{}).
		Where("balance < 0").
		Update("balance", decimal.Zero).Error; err != nil {
		return fmt.Errorf("修复子账号负数余额失败: %v", err)
	}

	// 修复精度问题
	if err := v.db.Model(&models.MasterAccount{}).
		Update("balance", gorm.Expr("ROUND(balance, 2)")).Error; err != nil {
		return fmt.Errorf("修复主账号余额精度失败: %v", err)
	}

	if err := v.db.Model(&models.SubAccount{}).
		Update("balance", gorm.Expr("ROUND(balance, 2)")).Error; err != nil {
		return fmt.Errorf("修复子账号余额精度失败: %v", err)
	}

	log.Println("余额问题修复完成")
	return nil
}

// RunFullValidation 运行完整验证
func (v *BalanceValidator) RunFullValidation() error {
	log.Printf("开始完整余额验证 - %s", time.Now().Format("2006-01-02 15:04:05"))

	// 1. 验证余额完整性
	if err := v.ValidateAllBalances(); err != nil {
		log.Printf("余额完整性验证失败: %v", err)
	}

	// 2. 生成余额报告
	if err := v.GenerateBalanceReport(); err != nil {
		log.Printf("生成余额报告失败: %v", err)
	}

	// 3. 修复余额问题
	if err := v.FixBalanceIssues(); err != nil {
		log.Printf("修复余额问题失败: %v", err)
	}

	log.Printf("完整余额验证完成 - %s", time.Now().Format("2006-01-02 15:04:05"))
	return nil
}
